#include "head.h"

// 服务端接收客户端gets命令的调用函数
// 第一个参数：子线程获取任务后和客户端通信的socket对象fd
// 第二个参数：gets 文件名  命令中文件名的绝对路径
int sendFile(int socket_fd, transport_protocol_t *msg)
{
    // url文件的路径（客户端视角）
    char buf2[1024] = {0};
    strcpy(buf2, msg->curr_path);
    if (strcmp(msg->curr_path, "/") == 0)
    {
        bzero(msg->curr_path, sizeof(msg->curr_path));
    }
    char url[1024];
    sprintf(url, "%s/%s", msg->curr_path, msg->buf);

    // 查表判断是否有此文件
    char sql_statement[1500];
    sprintf(sql_statement,
            "select file_hash from bd_file where user_id='%s' and filename='%s' and url='%s' and delete_flag=0 and upload_flag=0",
            msg->user_id, msg->buf, url);
    // printf("SQL1:%s\n", sql_statement);
    mysql_query(&msg->my_sql, sql_statement);
    MYSQL_RES *result = mysql_store_result(&msg->my_sql);
    MYSQL_ROW row = mysql_fetch_row(result);

    int is_file = 0;
    if (row == 0)
    {
        printf("服务器没有此文件,gets命令执行结束!\n");
        // 通知服务端
        is_file = -1;
        send(socket_fd, &is_file, sizeof(int), MSG_NOSIGNAL);
        return 0;
    }
    send(socket_fd, &is_file, sizeof(int), MSG_NOSIGNAL);

    char hash_val[100] = {0};
    strcpy(hash_val, row[0]);

    mysql_free_result(result);

    // 打开要上传的文件
    int file_fd = open(hash_val, O_RDWR);

    // 获取文件大小
    struct stat st;
    memset(&st, 0, sizeof(st));
    fstat(file_fd, &st);

    // 发送文件前先接受客户端传输过来的已下载文件大小
    off_t updated_size = 0;
    recv(socket_fd, &updated_size, sizeof(off_t), MSG_WAITALL);
    printf("客户端已下载文件大小:%ld\n", updated_size);

    int updated_num = updated_size / 4096; // updated_num表示已下载文件所占的页数

    // 客户端已下载文件大小为0
    if (updated_size == 0)
    {
        // 把文件大小发送给客户端
        send(socket_fd, &st.st_size, sizeof(off_t), MSG_NOSIGNAL);

        // 使用sendfile: 零拷贝
        sendfile(socket_fd, file_fd, NULL, st.st_size);

        // printf("close \n");
        close(file_fd);
        return 0;
    }

    // 把要发送的文件大小发送给客户端
    off_t send_size = st.st_size - updated_num * 4096;
    send(socket_fd, &send_size, sizeof(off_t), MSG_NOSIGNAL);

    // 使用sendfile: 零拷贝
    off_t off_set = (off_t)updated_num * 4096;
    sendfile(socket_fd, file_fd, &off_set, send_size);

    // printf("close \n");
    close(file_fd);
    return 0;
}
